package org.easymodelers.expression;

public class ExpressionParser {
	private String expression;
	
	public ExpressionParser(String expression) {
		this.expression = expression;
	}

	public ExpressionData parse() {
		ExpressionData data = new ExpressionData();

		if (!expression.startsWith("${") || !expression.endsWith("}")) {
			String message = "An expression must start with ${ and end with } - expression: "+expression;
			throw new ExpressionEvaluationException(message);
		}
		
		//Removing ${
		String tmpExpression = expression.substring(2);
		//Getting function
		int index = tmpExpression.indexOf("(");
		if (index!=-1) {
			String functionName = tmpExpression.substring(0, index);
			data.setFunction(functionName);
			tmpExpression = tmpExpression.substring(index+1);
			index = tmpExpression.indexOf(")");
			if (index!=-1) {
				tmpExpression = tmpExpression.substring(0, index);
				tmpExpression += "}";
			}
		}

		//Getting namespace
		index = tmpExpression.indexOf(":");
		if (index!=-1) {
			String namespace = tmpExpression.substring(0, index);
			tmpExpression = tmpExpression.substring(index+1);
			data.setNamespace(namespace);
		} else {
			String contextValue = tmpExpression.substring(0, tmpExpression.length()-1);
			data.setContextValue(contextValue);
			return data;
		}

		boolean typeHandled = false;
		index = tmpExpression.indexOf("[");
		if (index!=-1) {
			//Getting type
			String type = tmpExpression.substring(0, index);
			tmpExpression = tmpExpression.substring(index+1);
			//Getting condition field name
			index = tmpExpression.indexOf("=");
			String conditionFieldName = tmpExpression.substring(0, index);
			tmpExpression = tmpExpression.substring(index+1);
			//Getting condition field value
			index = tmpExpression.indexOf("]");
			String tmpConditionFieldValue = tmpExpression.substring(0, index);
			if (tmpConditionFieldValue.startsWith("'") && tmpConditionFieldValue.endsWith("'")) {
				String conditionFieldValue = tmpExpression.substring(1, index-1);
				tmpExpression = tmpExpression.substring(index+1);
				data.setType(type);
				typeHandled = true;
				data.setConditionFieldName(conditionFieldName);
				data.setConditionFieldValue(conditionFieldValue);
			} else {
				tmpExpression = tmpExpression.substring(index+1);
				data.setType(type);
				typeHandled = true;
				data.setConditionFieldName(conditionFieldName);
				data.setConditionFieldContextValue(tmpConditionFieldValue);
			}
		}
		
		index = tmpExpression.indexOf(".");
		if (index!=-1) {
			if (!typeHandled) {
				//Getting type
				String type = tmpExpression.substring(0, index);
				tmpExpression = tmpExpression.substring(index+1);
				data.setType(type);
			} else {
				tmpExpression = tmpExpression.substring(1);
			}
			//Getting field name
			String fieldName = tmpExpression.substring(0, tmpExpression.length()-1);
			data.setFieldName(fieldName);
		} else {
			if (!typeHandled) {
				String type = tmpExpression.substring(0, tmpExpression.length()-1);
				data.setType(type);
			}
		}

		return data;
	}
}
